package com.puzzlebazar.client.user;

import com.google.gwt.user.client.Window;
import com.puzzlebazar.client.main.control.TabbedSubstate;
import com.puzzlebazar.client.main.view.TabbedView;
import com.puzzlebazar.client.user.SettingsGeneralView.ProfileEditionCallback;
import com.puzzlebazar.client.util.AsyncCallbackLock;
import com.puzzlebazar.client.util.ConnectionLock;

public class SettingsGeneralSubstate extends TabbedSubstate {	

	public static final String TAB_NAME = "General";
	public static final String STATE_NAME = "General";

	private final MyProfileEditionCallback profileModifiedCallback = new MyProfileEditionCallback();
	private ConnectionLock savingLock = new ConnectionLock("Saving...");
	
	private final UserModel model;	

	private SettingsGeneralView settingsGeneralView = null;

	public SettingsGeneralSubstate( UserModel model, TabbedView view, SettingsController controller ) {
		super( view, controller );

		this.model = model;
		
		savingLock.setGlobalLock(true);
	}

	@Override
	public String getTabName() {
		return TAB_NAME;
	}

	@Override
	public String getStateName() {
		return STATE_NAME;
	}

	@Override
	public void enter() {
		super.enter();
		
		if( settingsGeneralView == null )
			settingsGeneralView = new SettingsGeneralView();

		settingsGeneralView.setRegistration( !model.isValid() );
		
		UserInfo userInfo = model.getUserInfo();
		if( userInfo == null ) {
			controller.backToPreviousState();
			return;
		}			
		
		settingsGeneralView.resetState( userInfo );
		
		view.setMainWidget( settingsGeneralView );

		enableCallbacks();
	
	}


	@Override
	public void exit() {
		super.exit();
		disableCallbacks();
	}
	
	public class MyProfileEditionCallback implements ProfileEditionCallback {

		@Override
		public void cancel() {
			controller.backToPreviousState();
		}

		@Override
		public void apply(UserInfo userInfo) {

			model.modifyUser( userInfo, 
					new AsyncCallbackLock<Integer>(savingLock) {
						@Override
						public void onFailure(Throwable caught) {
							super.onFailure(caught);
							Window.alert( "Connection to the server has failed" );
						}
						@Override
						public void onSuccess(Integer result) {
							super.onSuccess(result);
							if( result == UserInfo.ErrorFlags.SUCCESS ) {
								controller.setConfirmStateChange( null );
								controller.forwardToPreviousState();
							}
							else {
								if( (result & SettingsGeneralView.UNHANDLED_ERRORS_MASK) != 0 )
									Window.alert( "An unknown error has occured, try modifying your settings again later." );
							}								
						}							
			} );
		}

		@Override
		public void modified( boolean isDifferent ) {
			if( isDifferent )
				controller.setConfirmStateChange( "Discard modifications?" );
			else
				controller.setConfirmStateChange( null );
		}
	}

	/**
	 * Turns all callbacks on
	 */
	private void enableCallbacks() {
		settingsGeneralView.addCallback( profileModifiedCallback );
	}

	/**
	 * Turns all defaults callbacks off
	 */
	private void disableCallbacks() {
		settingsGeneralView.removeCallback( profileModifiedCallback );
	}

	@Override
	public void release() {
		super.release();
		disableCallbacks();
		if( settingsGeneralView != null )		
			settingsGeneralView.release();
		settingsGeneralView = null;
	}
}